package com.atguigu.daijia.customer.service.impl;

import com.atguigu.daijia.common.execption.GuiguException;
import com.atguigu.daijia.common.result.Result;
import com.atguigu.daijia.common.result.ResultCodeEnum;
import com.atguigu.daijia.customer.service.OrderService;
import com.atguigu.daijia.dispatch.client.NewOrderFeignClient;
import com.atguigu.daijia.driver.client.DriverInfoFeignClient;
import com.atguigu.daijia.map.client.LocationFeignClient;
import com.atguigu.daijia.map.client.MapFeignClient;
import com.atguigu.daijia.model.entity.order.OrderInfo;
import com.atguigu.daijia.model.form.customer.ExpectOrderForm;
import com.atguigu.daijia.model.form.customer.SubmitOrderForm;
import com.atguigu.daijia.model.form.map.CalculateDrivingLineForm;
import com.atguigu.daijia.model.form.order.OrderInfoForm;
import com.atguigu.daijia.model.form.rules.FeeRuleRequestForm;
import com.atguigu.daijia.model.vo.base.PageVo;
import com.atguigu.daijia.model.vo.customer.ExpectOrderVo;
import com.atguigu.daijia.model.vo.dispatch.NewOrderTaskVo;
import com.atguigu.daijia.model.vo.driver.DriverInfoVo;
import com.atguigu.daijia.model.vo.map.DrivingLineVo;
import com.atguigu.daijia.model.vo.map.OrderLocationVo;
import com.atguigu.daijia.model.vo.order.CurrentOrderInfoVo;
import com.atguigu.daijia.model.vo.rules.FeeRuleResponseVo;
import com.atguigu.daijia.order.client.OrderInfoFeignClient;
import com.atguigu.daijia.rules.client.FeeRuleFeignClient;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.Objects;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class OrderServiceImpl implements OrderService {
    @Resource
    OrderInfoFeignClient orderInfoFeignClient;
    @Resource
    private MapFeignClient mapFeignClient;

    @Resource
    private FeeRuleFeignClient feeRuleFeignClient;
    @Resource
    private NewOrderFeignClient newOrderFeignClient;
    @Resource
    private DriverInfoFeignClient driverInfoFeignClient;
    @Resource
    private LocationFeignClient locationFeignClient;

    /*
     * @param expectOrderForm 
     * @==============History===============<br/>;
     * @Description //   乘客预估订单数据
     * @Date 2024/8/9
     * @Author < a href="15991488967@163.com">chen</ a>;
     */
    @Override
    public ExpectOrderVo expectOrder(ExpectOrderForm expectOrderForm) {
        // 获取驾驶线路
        CalculateDrivingLineForm calculateDrivingLineForm = new CalculateDrivingLineForm();
        BeanUtils.copyProperties(expectOrderForm,calculateDrivingLineForm);
        Result<DrivingLineVo> drivingLineVoResult = mapFeignClient.calculateDrivingLine(calculateDrivingLineForm);
        DrivingLineVo drivingLineVo = drivingLineVoResult.getData();
        // 获取订单费用
        FeeRuleRequestForm calculateOrderFeeForm = new FeeRuleRequestForm();
        calculateOrderFeeForm.setDistance(drivingLineVo.getDistance());
        calculateOrderFeeForm.setStartTime(new Date());
        calculateOrderFeeForm.setWaitMinute(0);
        Result<FeeRuleResponseVo> feeRuleResponseVoResult = feeRuleFeignClient.calculateOrderFee(calculateOrderFeeForm);
        FeeRuleResponseVo feeRuleResponseVo = feeRuleResponseVoResult.getData();

        // 封装ExpectOrderVo
        ExpectOrderVo expectOrderVo = new ExpectOrderVo();
        expectOrderVo.setDrivingLineVo(drivingLineVo);
        expectOrderVo.setFeeRuleResponseVo(feeRuleResponseVo);
        return expectOrderVo;
    }


    /*
     * @param customerId
     * @==============History===============<br/>;
     * @Description //   获取乘客当前订单
     * @Date 2024/8/9
     * @Author < a href="15991488967@163.com">chen</ a>;
     */
    @Override
    public CurrentOrderInfoVo searchCustomerCurrentOrder(Long customerId) {
        Result<CurrentOrderInfoVo> orderResult = orderInfoFeignClient.searchCustomerCurrentOrder(customerId);
        return orderResult.getData();
    }

    /*
     * @param orderId 
     * @==============History===============<br/>;
     * @Description //   根据订单id获取订单状态
     * @Date 2024/8/9
     * @Author < a href="15991488967@163.com">chen</ a>;
     */
    @Override
    public Integer getOrderStatus(Long orderId) {
        return orderInfoFeignClient.getOrderStatus(orderId).getData();
    }

    /*
     * @param customerId
     * @param page
     * @param limit 
     * @==============History===============<br/>;
     * @Description //   获取乘客订单分页列表
     * @Date 2024/8/9
     * @Author < a href="15991488967@163.com">chen</ a>;
     */
    @Override
    public PageVo findCustomerOrderPage(Long customerId, Long page, Long limit) {
        Result<PageVo> customerOrderPage = orderInfoFeignClient.findCustomerOrderPage(customerId, page, limit);
        return customerOrderPage.getData();
    }

    @Override
    public Long submitOrder(SubmitOrderForm submitOrderForm) {
        // 重新计算预估的订单费用和预估的订单里程
        CalculateDrivingLineForm calculateDrivingLineForm = new CalculateDrivingLineForm();
        BeanUtils.copyProperties(submitOrderForm, calculateDrivingLineForm);
        DrivingLineVo drivingLineVo = mapFeignClient.calculateDrivingLine(calculateDrivingLineForm).getData();

        FeeRuleRequestForm calculateOrderFeeForm = new FeeRuleRequestForm();
        calculateOrderFeeForm.setDistance(drivingLineVo.getDistance());
        calculateOrderFeeForm.setStartTime(new Date());
        calculateOrderFeeForm.setWaitMinute(0);
        FeeRuleResponseVo feeRuleResponseVo = feeRuleFeignClient.calculateOrderFee(calculateOrderFeeForm).getData();


        // 保存订单信息
        OrderInfoForm orderInfoForm = new OrderInfoForm();
        orderInfoForm.setExpectDistance(drivingLineVo.getDistance());
        orderInfoForm.setExpectAmount(feeRuleResponseVo.getTotalAmount());
        Result<Long> orderInfoResult = orderInfoFeignClient.saveOrderInfo(orderInfoForm);

        Long orderId = orderInfoResult.getData();// 订单id

        // 启动任务调度,轮询满足接单条件的司机信息
        //任务调度：查询附近可以接单司机
        NewOrderTaskVo newOrderDispatchVo = new NewOrderTaskVo();
        newOrderDispatchVo.setOrderId(orderId);
        newOrderDispatchVo.setStartLocation(orderInfoForm.getStartLocation());
        newOrderDispatchVo.setStartPointLongitude(orderInfoForm.getStartPointLongitude());
        newOrderDispatchVo.setStartPointLatitude(orderInfoForm.getStartPointLatitude());
        newOrderDispatchVo.setEndLocation(orderInfoForm.getEndLocation());
        newOrderDispatchVo.setEndPointLongitude(orderInfoForm.getEndPointLongitude());
        newOrderDispatchVo.setEndPointLatitude(orderInfoForm.getEndPointLatitude());
        newOrderDispatchVo.setExpectAmount(orderInfoForm.getExpectAmount());
        newOrderDispatchVo.setExpectDistance(orderInfoForm.getExpectDistance());
        newOrderDispatchVo.setExpectTime(drivingLineVo.getDuration());
        newOrderDispatchVo.setFavourFee(orderInfoForm.getFavourFee());
        newOrderDispatchVo.setCreateTime(new Date());
        // 远程调用
        Long jobId = newOrderFeignClient.addAndStartTask(newOrderDispatchVo).getData();

        return orderInfoResult.getData();
    }

    /*
     * @param orderId     订单
     * @param customerId  乘客id
     * @==============History===============<br/>
     * @Description //   根据订单id获取司机基本信息
     * @Date 2024-9-10 22:45
     * @Author < a href="15991488967@163.com">chen</ a>
     * @return com.atguigu.daijia.model.vo.driver.DriverInfoVo
     */
    @Override
    public DriverInfoVo getDriverInfo(Long orderId, Long customerId)
    {
        Result<OrderInfo> orderInfoResult = orderInfoFeignClient.getOrderInfo(orderId);
        if(Objects.equals(orderInfoResult.getCode(), ResultCodeEnum.SUCCESS.getCode()))
        {
            OrderInfo orderInfo = orderInfoResult.getData();

            if(!Objects.equals(orderInfo.getCustomerId(), customerId))
            {
                throw new GuiguException(ResultCodeEnum.DATA_ERROR);
            }

            Result<DriverInfoVo> driverInfoResult = driverInfoFeignClient.getDriverInfo(orderInfo.getDriverId());

            if(Objects.equals(driverInfoResult.getCode(), ResultCodeEnum.SUCCESS.getCode()))
            {
                return driverInfoResult.getData();
            }
        }
        throw new GuiguException(ResultCodeEnum.DATA_ERROR);
    }

    /*
     * @param orderId   订单id
     * @==============History===============<br/>
     * @Description //   司机赶往代驾起始点:获取订单经纬度位置
     * @Date 2024-9-10 22:58
     * @Author < a href="15991488967@163.com">chen</ a>
     * @return com.atguigu.daijia.model.vo.map.OrderLocationVo
     */
    @Override
    public OrderLocationVo getCacheOrderLocation(Long orderId)
    {
        Result<OrderLocationVo> cacheOrderLocationResult = locationFeignClient.getCacheOrderLocation(orderId);
        if(Objects.equals(cacheOrderLocationResult.getCode(), ResultCodeEnum.SUCCESS.getCode()))
        {
            return cacheOrderLocationResult.getData();
        }
        throw new GuiguException(ResultCodeEnum.FAIL);
    }

    
    /*
     * @param calculateDrivingLineForm
     * @==============History===============<br/>
     * @Description //   计算司机到达出发点的最佳驾驶线路
     * @Date 2024-9-10 23:03 
     * @Author < a href="15991488967@163.com">chen</ a>
     * @return com.atguigu.daijia.model.vo.map.DrivingLineVo
     */
    @Override
    public DrivingLineVo calculateDrivingLine(CalculateDrivingLineForm calculateDrivingLineForm)
    {
        Result<DrivingLineVo> drivingLineVoResult = mapFeignClient.calculateDrivingLine(calculateDrivingLineForm);
        if(Objects.equals(drivingLineVoResult.getCode(), ResultCodeEnum.SUCCESS.getCode()))
        {
            return drivingLineVoResult.getData();
        }
        throw new GuiguException(ResultCodeEnum.FAIL);
    }
}
